package org.wattdepot.cli.commands;

import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.client.BadXmlException;
import org.wattdepot.client.MiscClientException;
import org.wattdepot.client.NotAuthorizedException;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.resource.property.jaxb.Property;
import org.wattdepot.resource.sensordata.jaxb.SensorData;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * This class contains a command that prints out data for a single sensor at a specified time for
 * the CommandLineInterface.
 * 
 * @author David Mau
 */
public class SensorTimeStampCommand implements WattDepotCliCommand {
  // Default client-server connection to use unless given one.
  private WattDepotClient client = new WattDepotClient(debug);

  /**
   * This constructor makes sure that the client really is connected to the server.
   * 
   * @param anotherClient Specifies if the user wants to use another WattDepot server
   * other than the default simulation one.
   */
  public SensorTimeStampCommand( String anotherClient ) {
    // If another client is provided
    if ( anotherClient != null ) {
      client = new WattDepotClient( anotherClient );
    }
    
    // Stop right away if we cannot contact server.
    if (!client.isHealthy()) {
      System.out.println("Failed to connect to " + client.getWattDepotUri());
      return;
    }
    // Indicate successful connection.
    //System.out.println("Connected to " + client.getWattDepotUri());
  }

  /**
   * This method returns a String that has data about a single sensor at a specified time. The
   * String is ready to print in a listing-type format. Created by David Mau.
   * 
   * @param args A list of arguments given to this command.
   * @return A String containing data about a single sensor.
   */
  public String doCommand(List<String> args) {
    String output;

    if (args.size() > 2) {
      output = tooManyArguments;
      output = output.concat(cr);
      return output;
    }
    if (args.size() < 2) {
      output = missingArguments;
      output = output.concat(cr);
      return output;
    }

    String source = args.get(0);
    String timestamp = args.get(1);

    SensorData data = null;
    XMLGregorianCalendar xmlTimeStamp = null;
    // Convert the String time stamp into an XML one.
    try {
      xmlTimeStamp = Tstamp.makeTimestamp(timestamp);
    }
    catch (Exception e) {
      output = badTimeStamp;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }

    // Try to collect data from the sensor using the source and converted time stamp.
    try {
      data = client.getSensorData(source, xmlTimeStamp);
    }
    catch (NotAuthorizedException e) {
      output = notAuthorized;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (ResourceNotFoundException e) {
      output = resourceNotFound;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (BadXmlException e) {
      output = badXml;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }
    catch (MiscClientException e) {
      output = miscClient;
      output = output.concat(e.toString());
      output = output.concat(cr);
      return output;
    }

    if (data == null) {
      output = noSensorData;
      output = output.concat(cr);
      return output;
    }
    else {
      output = String.format("Tool: %s", data.getTool());
      output = output.concat(cr);
      output = output.concat(String.format("Source: %s", source));
      output = output.concat(cr);
      output = output.concat("Properties: ");
      List<Property> properties = data.getProperties().getProperty();
      for (Property single : properties) {
        output =
            output.concat(String.format("(%s: %s) ", single.getKey(), single.getValue()) );
      }

      output = output.concat(cr);
    }

    return output;
  }
}
